Detailed explanation of the method of cutting wav audio file by java [with external jar package download]

  • 2021-07-26 07:48:56
  • OfStack

This paper describes the method of cutting wav audio files by java. Share it for your reference, as follows:


import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.MultimediaInfo;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
 * wav Audio file interception tool 
 *  (Applicable to the bit rate of 128kbps Adj. wav Audio files, the length of header information of such audio files 44 Bytes) 
 * @author lwj
 *
 */
public class WavCut {
  /**
   *  Interception wav Audio file 
   * @param sourcepath  Source file address 
   * @param targetpath  Destination file address 
   * @param start  Intercept start time (seconds) 
   * @param end  Intercept end time (seconds) 
   *
   * return  Successful interception returns true Otherwise, return false
   */
  public static boolean cut(String sourcefile, String targetfile, int start, int end) {
    try{
      if(!sourcefile.toLowerCase().endsWith(".wav") || !targetfile.toLowerCase().endsWith(".wav")){
        return false;
      }
      File wav = new File(sourcefile);
      if(!wav.exists()){
        return false;
      }
      long t1 = getTimeLen(wav); // Total duration ( Seconds )
      if(start<0 || end<=0 || start>=t1 || end>t1 || start>=end){
        return false;
      }
      FileInputStream fis = new FileInputStream(wav);
      long wavSize = wav.length()-44; // Audio data size ( 44 For 128kbps Bit rate wav File header length) 
      long splitSize = (wavSize/t1)*(end-start); // Size of Intercepted Audio Data 
      long skipSize = (wavSize/t1)*start; // Size of audio data skipped during interception 
      int splitSizeInt = Integer.parseInt(String.valueOf(splitSize));
      int skipSizeInt = Integer.parseInt(String.valueOf(skipSize));
      ByteBuffer buf1 = ByteBuffer.allocate(4); // Store file size ,4 Representative 1 A int Number of bytes occupied 
      buf1.putInt(splitSizeInt+36); // Put in file length information 
      byte[] flen = buf1.array(); // Represents file length 
      ByteBuffer buf2 = ByteBuffer.allocate(4); // Store audio data size, 4 Representative 1 A int Number of bytes occupied 
      buf2.putInt(splitSizeInt); // Input data length information 
      byte[] dlen = buf2.array(); // Represents data length 
      flen = reverse(flen); // Array inversion 
      dlen = reverse(dlen);
      byte[] head = new byte[44]; // Definition wav Header information array 
      fis.read(head, 0, head.length); // Read source wav File header information 
      for(int i=0; i<4; i++){ //4 Representative 1 A int Number of bytes occupied 
        head[i+4] = flen[i]; // Replace the file length in the original header information 
        head[i+40] = dlen[i]; // Replace the data length in the original header information 
      }
      byte[] fbyte = new byte[splitSizeInt+head.length]; // Store the intercepted audio data 
      for(int i=0; i<head.length; i++){ // Put in the modified header information 
        fbyte[i] = head[i];
      }
      byte[] skipBytes = new byte[skipSizeInt]; // Store audio data skipped during interception 
      fis.read(skipBytes, 0, skipBytes.length); // Skip data that does not need to be intercepted 
      fis.read(fbyte, head.length, fbyte.length-head.length); // Read the data to be intercepted into the target array 
      fis.close();
      File target = new File(targetfile);
      if(target.exists()){ // Delete the destination file if it already exists 
        target.delete();
      }
      FileOutputStream fos = new FileOutputStream(target);
      fos.write(fbyte);
      fos.flush();
      fos.close();
    }catch(IOException e){
      e.printStackTrace();
      return false;
    }
    return true;
  }
  /**
   *  Get the total duration of audio files 
   * @param filePath  File path 
   * @return
   */
  public static long getTimeLen(File file){
    long tlen = 0;
    if(file!=null && file.exists()){
      Encoder encoder = new Encoder();
      try {
         MultimediaInfo m = encoder.getInfo(file);
         long ls = m.getDuration();
         tlen = ls/1000;
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    return tlen;
  }
  /**
  *  Array inversion 
  * @param array
  */
  public static byte[] reverse(byte[] array){
    byte temp;
    int len=array.length;
    for(int i=0;i<len/2;i++){
      temp=array[i];
      array[i]=array[len-1-i];
      array[len-1-i]=temp;
    }
    return array;
  }
  public static void main(String[] args){
    System.out.println(cut("f:\\111.wav","f:\\111-cut_0_10.wav",0,10));
    System.out.println(cut("f:\\111.wav","f:\\111-cut_10_20.wav",10,20));
    System.out.println(cut("f:\\111.wav","f:\\111-cut_20_28.wav",20,28));
  }
}

Attention must be paid to the header information when cutting wave audio files. The header information of wave files with 128kbps bit rate occupies 44 bytes.

The header information can be taken as an object, and the header information can be obtained by ByteBuffer.

Note: The wave file has an array inversion for each attribute in the header byte array

The wave header information object model is as follows:


/**
 * wave File header information 
 * @author lwj
 *
 */
public class Head {
  public int riff_id;      //4 byte , 'RIFF'
  public int file_size;     //4 byte ,  File length (data length +36 ) 
  public int riff_type;     //4 byte , 'WAVE'
  public int fmt_id;      //4 byte , 'fmt'
  public int fmt_size;     //4 byte ,  The value is 16 Or 18 , 18 Then the information is finally attached 
  public short fmt_tag;     //2 byte ,  Coding mode, 1 Be general 0x0001
  public short fmt_channel;   //2 byte ,  Number of vocal tracks, 1-- Mono; 2-- Dual channel 
  public int fmt_samplesPerSec;//4 byte ,  Sampling frequency 
  public int avgBytesPerSec;  //4 byte ,  Bytes per second required , Record the amount of data per second 
  public short blockAlign;   //2 byte ,  Data block alignment unit ( Number of bytes required per sample )
  public short bitsPerSample;  //2 byte ,  Required for each sample bit Number 
  public int data_id;      //4 byte ,  Character data
  public int data_size;     //4 byte ,  Data length 
  public int getRiff_id() {
    return riff_id;
  }
  public void setRiff_id(int riff_id) {
    this.riff_id = riff_id;
  }
  public int getFile_size() {
    return file_size;
  }
  public void setFile_size(int file_size) {
    this.file_size = file_size;
  }
  public int getRiff_type() {
    return riff_type;
  }
  public void setRiff_type(int riff_type) {
    this.riff_type = riff_type;
  }
  public int getFmt_id() {
    return fmt_id;
  }
  public void setFmt_id(int fmt_id) {
    this.fmt_id = fmt_id;
  }
  public int getFmt_size() {
    return fmt_size;
  }
  public void setFmt_size(int fmt_size) {
    this.fmt_size = fmt_size;
  }
  public short getFmt_tag() {
    return fmt_tag;
  }
  public void setFmt_tag(short fmt_tag) {
    this.fmt_tag = fmt_tag;
  }
  public short getFmt_channel() {
    return fmt_channel;
  }
  public void setFmt_channel(short fmt_channel) {
    this.fmt_channel = fmt_channel;
  }
  public int getFmt_samplesPerSec() {
    return fmt_samplesPerSec;
  }
  public void setFmt_samplesPerSec(int fmt_samplesPerSec) {
    this.fmt_samplesPerSec = fmt_samplesPerSec;
  }
  public int getAvgBytesPerSec() {
    return avgBytesPerSec;
  }
  public void setAvgBytesPerSec(int avgBytesPerSec) {
    this.avgBytesPerSec = avgBytesPerSec;
  }
  public short getBlockAlign() {
    return blockAlign;
  }
  public void setBlockAlign(short blockAlign) {
    this.blockAlign = blockAlign;
  }
  public short getBitsPerSample() {
    return bitsPerSample;
  }
  public void setBitsPerSample(short bitsPerSample) {
    this.bitsPerSample = bitsPerSample;
  }
  public int getData_id() {
    return data_id;
  }
  public void setData_id(int data_id) {
    this.data_id = data_id;
  }
  public int getData_size() {
    return data_size;
  }
  public void setData_size(int data_size) {
    this.data_size = data_size;
  }
}

Attachment is the external jar package that the wave cutting program depends on: jave-1. 0.2

More readers interested in java algorithm can check the topics of this site: "Summary of Java File and Directory Operation Skills", "Java Data Structure and Algorithm Tutorial", "Summary of Java Operation DOM Node Skills" and "Summary of Java Cache Operation Skills"

I hope this article is helpful to everyone's java programming.


Related articles: